package com.ynet.middleground.mobile.approve.service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiV2UserGetRequest;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.google.common.base.Throwables;
import com.taobao.api.ApiException;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.middleground.mobile.approve.constant.SystemConstant;
import com.ynet.middleground.mobile.approve.constant.UrlConstant;
import com.ynet.middleground.mobile.approve.response.UserDTO;
import com.ynet.middleground.mobile.approve.utils.ApiHelper;
import com.ynet.middleground.user.dto.EmployeeInfoDto;
import com.ynet.middleground.user.dto.UserInfoDto;

/**
 * @ClassName AuthService
 * @Description 调用钉钉接口
 * @Author liwq
 * @Date 2021/3/22 16:36
 * @Version 1.0
 */
@Service
public class AuthService {

    @Autowired
    ApiHelper apiHelper;

    @Autowired
    UserCenterService userCenterService;

    /**
     * 访问钉钉API 获取用户信息
     *
     * @param ddUserId 钉钉userId
     * @return 用户名称或错误信息
     */
    @Transactional(rollbackFor = Exception.class)
    public UserDTO getUser(String ddUserId) {
        // step1: 参数校验，准备等
        if (StringUtils.isEmpty(ddUserId)) {
            return null;
        }
        OapiV2UserGetResponse response;
        UserDTO user = new UserDTO();

        // step2: 获取accessToken
        String accessToken = apiHelper.getAccessToken();

        // step3: 整理参数，并转调钉钉API
        DingTalkClient client = new DefaultDingTalkClient(UrlConstant.URL_USER_GET);
        OapiV2UserGetRequest request = new OapiV2UserGetRequest();
        request.setUserid(ddUserId);
        request.setHttpMethod("GET");
        try {
            IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "钉钉查询用户信息服务,req: {}", ddUserId);
            response = client.execute(request, accessToken);
            IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "钉钉查询用户信息服务,response: {}",
                JSON.toJSONString(response));
        } catch (ApiException e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "getUser failed, case: {}",
                Throwables.getStackTraceAsString(e));
            throw new BusinessException(e.getErrMsg(), e.getErrCode());
        }
        if (!response.isSuccess()) {
            throw new BusinessException(response.getErrmsg(), String.valueOf(response.getErrcode()));
        }
        OapiV2UserGetResponse.UserGetResponse result = response.getResult();
        // step4: 整理并返回
        user.setName(result.getName());
        user.setDingtalkUserId(result.getUserid());
        user.setAvatar(result.getAvatar());
        user.setMobile(result.getMobile());
        return user;
    }

    /**
     * 根据手机号查询用户中心数据并进行绑定
     * 
     * @param user
     * @return
     */
    public UserDTO bindDingtalkUser(UserDTO user) {
        List<EmployeeInfoDto> employees =
            userCenterService.queryEmployee(null, SystemConstant.CHANNEL, user.getMobile());
        if (employees != null && !employees.isEmpty()) {
            if (employees.size() > 1) {
                // 有多条数据，进行 userid 去重复
                employees = employees.stream()
                    .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(EmployeeInfoDto::getUserId))),
                        ArrayList::new));
                IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(),
                    "登陆-港内员工数据查询服务,req: {}, employees: {}", user.getMobile(), JSON.toJSONString(employees));
                // 过滤完之后仍然有多条，则说说明手机号对应多条用户数据
                if (employees.size() > 1) {
                    throw new BusinessException("该手机号对应多条用户信息", "ECMA0001");
                }
            }
            EmployeeInfoDto employeeInfoDto = employees.get(0);
            UserInfoDto userInfo = userCenterService.getUserInfo(employeeInfoDto.getUserId(),
                employeeInfoDto.getChannel(), employeeInfoDto.getUserId(), employeeInfoDto.getOrganizationalId());
            if (userInfo == null || userInfo.getUserBaseInformationDto() == null) {
                throw new BusinessException("无该用户信息", "ECMA0001");
            }
            String dingtalkUserid = userInfo.getUserBaseInformationDto().getDingtalkUserid();
            if (StringUtils.isBlank(dingtalkUserid)) {
                userCenterService.bindDingtalk(employeeInfoDto.getUserId(), user.getDingtalkUserId(),
                    employeeInfoDto.getChannel());
            }
            user.setUserId(employeeInfoDto.getUserId());
            user.setEmployeeInfoDto(employeeInfoDto);
        } else {
            throw new BusinessException("无该用户信息", "ECMA0001");
        }
        return user;
    }

}
